package com.mcxx.modules.miniSalvation.order.service.write;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.mcxx.common.exception.BizException;
import com.mcxx.modules.base.utils.QueryParamUtil;
import com.mcxx.modules.filemanage.easypoi.util.ExportExcelService;
import com.mcxx.modules.filemanage.file.service.FileService;
import com.mcxx.modules.miniSalvation.family.entity.FamilyMemberEntity;
import com.mcxx.modules.miniSalvation.family.service.read.FamilyMemberReadService;
import com.mcxx.modules.miniSalvation.fundpay.service.read.FundPayReadService;
import com.mcxx.modules.miniSalvation.order.dao.read.OrderCareLinkReadDao;
import com.mcxx.modules.miniSalvation.order.dao.write.OrderCareLinkWriteDao;
import com.mcxx.modules.miniSalvation.order.dao.write.OrderCaregiversWriteDao;
import com.mcxx.modules.miniSalvation.order.dao.write.OrderCertWriteDao;
import com.mcxx.modules.miniSalvation.order.dto.OrderCareLinkExcelDTO;
import com.mcxx.modules.miniSalvation.order.dto.OrderCaregiversDTO;
import com.mcxx.modules.miniSalvation.order.entity.OrderCareLinkEntity;
import com.mcxx.modules.miniSalvation.order.entity.OrderCaregiversEntity;
import com.mcxx.modules.miniSalvation.order.param.CaregiverParam;
import com.mcxx.modules.miniSalvation.order.service.read.OrderCareLinkReadService;
import com.mcxx.modules.miniSalvation.order.service.read.OrderCaregiversReadService;
import com.mcxx.modules.miniSalvation.order.service.read.OrderCertReadService;
import com.mcxx.modules.system.entity.TaskExportEntity;
import com.mcxx.modules.system.service.write.TaskExportWriteService;
import com.mcxx.redis.client.RedisClusterUtils;
import com.mcxx.util.Constant;
import com.mcxx.util.FailureCode;
import com.yinhai.ta404.component.audit.vo.ExcelInfo;
import com.yinhai.ta404.core.security.vo.UserAccountVo;
import com.yinhai.ta404.core.transaction.annotation.TaTransactional;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@Service
@TaTransactional
public class OrderCaregiversWriteService {
    private final static Logger logger = LoggerFactory.getLogger(OrderCaregiversWriteService.class);

    @Autowired
    private OrderCaregiversWriteDao orderCaregiversWriteDao;
    @Autowired
    private OrderCareLinkWriteDao orderCareLinkWriteDao;
    @Autowired
    private FamilyMemberReadService familyMemberReadService;
    @Autowired
    private ExportExcelService exportExcelService;
    @Autowired
    private TaskExportWriteService taskExportWriteService;
    @Autowired
    private FileService fileService;
    @Autowired
    private OrderCareLinkReadDao orderCareLinkReadDao;
    @Autowired
    private OrderCertReadService orderCertReadService;
    @Autowired
    private OrderCertWriteDao orderCertWriteDao;
    @Autowired
    private OrderCaregiversReadService orderCaregiversReadService;
    @Autowired
    private OrderCareLinkReadService orderCareLinkReadService;
    @Autowired
    private FundPayReadService fundPayReadService;
    @Autowired
    private RedisClusterUtils redisClusterUtils;



    public int insert(OrderCaregiversEntity orderCaregivers) {
    	return orderCaregiversWriteDao.insert(orderCaregivers);
    }


    public int insertIgnoreNull(OrderCaregiversEntity orderCaregivers) {
    	return orderCaregiversWriteDao.insertIgnoreNull(orderCaregivers);
    }


    public int update(OrderCaregiversEntity orderCaregivers) {
    	return orderCaregiversWriteDao.update(orderCaregivers);
    }


    public int updateIgnoreNull(OrderCaregiversEntity orderCaregivers) {
    	return orderCaregiversWriteDao.updateIgnoreNull(orderCaregivers);
    }


    public int delete(OrderCaregiversEntity orderCaregivers) {
    	return orderCaregiversWriteDao.delete(orderCaregivers);
    }


    private void updateCaregivers(OrderCaregiversDTO caregiverDto){
        OrderCaregiversEntity caregiverEntity = new OrderCaregiversEntity();
        BeanUtils.copyProperties(caregiverDto,caregiverEntity);
        caregiverEntity.setState("01");
        caregiverEntity.setAccountName(caregiverDto.getName());
        caregiverEntity.setId(caregiverDto.getId());
        caregiverEntity.setAreaCodeCz(caregiverDto.getAreaCodeCz());
        caregiverEntity.setMechanismName(caregiverDto.getMechanismName());
        caregiverEntity.setAreaCode(caregiverDto.getAreaCode());
        caregiverEntity.setUpdateTime(new Date());
        orderCaregiversWriteDao.updateIgnoreNull(caregiverEntity);
    }

    private void insertCaregivers(OrderCaregiversDTO caregiverDto){
        OrderCaregiversEntity caregiverEntity = new OrderCaregiversEntity();
        BeanUtils.copyProperties(caregiverDto,caregiverEntity);
        caregiverEntity.setState("01");
        caregiverEntity.setAccountName(caregiverDto.getName());
        caregiverEntity.setId(caregiverDto.getId());
        caregiverEntity.setAreaCodeCz(caregiverDto.getAreaCodeCz());
        caregiverEntity.setAreaCode(caregiverDto.getAreaCode());
        caregiverEntity.setMechanismName(caregiverDto.getMechanismName());
        caregiverEntity.setCreateTime(new Date());
        caregiverEntity.setUpdateTime(new Date());

        orderCaregiversWriteDao.insertIgnoreNull(caregiverEntity);
    }

    private void insertCareLink(OrderCaregiversDTO caregiverDto){
        OrderCareLinkEntity careLinkEntity = new OrderCareLinkEntity();
        careLinkEntity.setId(IdUtil.simpleUUID());
        careLinkEntity.setMemName(caregiverDto.getMemberName());
        careLinkEntity.setMemberId(caregiverDto.getMemberId());
        careLinkEntity.setMemIdcard(caregiverDto.getMemberIdcard());
        careLinkEntity.setOrderId(caregiverDto.getOrderId());
        careLinkEntity.setState("01");
        careLinkEntity.setCareId(caregiverDto.getId());
        careLinkEntity.setCareIdcard(caregiverDto.getIdcard());
        careLinkEntity.setCareName(caregiverDto.getName());
        careLinkEntity.setCareBank(caregiverDto.getBankCode());
        //careLinkEntity.setAccountName(caregiverDto.getAccountName());
        careLinkEntity.setStartMonth(DateUtil.beginOfMonth(new Date()).toString("yyyyMM"));
        careLinkEntity.setEndMonth("210001");
        careLinkEntity.setAccount(caregiverDto.getAccount());
        careLinkEntity.setBankName(caregiverDto.getBankName());
        careLinkEntity.setCaregiverRelation(caregiverDto.getCaregiverRelation());
        careLinkEntity.setCreateTime(new Date());
        careLinkEntity.setUpdateTime(new Date());
        orderCareLinkWriteDao.insertIgnoreNull(careLinkEntity);
    }


    public void addCaregiver(OrderCaregiversDTO caregiverDto, UserAccountVo accountVo) {

        this.verifyOrderCaregiver(caregiverDto,caregiverDto.getMemberId(),caregiverDto.getId(),caregiverDto.getCaregiverType());

        String memberKey = "Care"+caregiverDto.getMemberIdcard();
        String msgKey = (String) redisClusterUtils.get(memberKey);
        if(msgKey == null) {
            redisClusterUtils.set(memberKey, memberKey, 5);
        }else{
            throw new BizException("-1","该对象正在登记照料人,请刷新列表后重试");
        }



        FamilyMemberEntity memberEntity = familyMemberReadService.getMemberStateByCardId(caregiverDto.getMemberIdcard());
        if (memberEntity == null) {
            throw new BizException(FailureCode.ERR_100018);
        }

        OrderCareLinkEntity orderCareLinkEntity = orderCareLinkReadService.getCareIdByIdCard(caregiverDto.getMemberIdcard());
        if(orderCareLinkEntity != null){
            throw new BizException("-1","该对象已经登记过照料人");
        }


        String curMonth = DateUtil.beginOfMonth(new Date()).toString("yyyy-MM");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        Date date = null;
        try {
            date = sdf.parse(curMonth);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        String rst = fundPayReadService.verifyFundPayCareThrow(Constant.BusinessCode.TEKUN, accountVo.getAreaCode(),
                caregiverDto.getStandType(), date, caregiverDto.getCaregiverType(),
                Constant.FundType.CAPITAL_FUND_PAY);

        if(StringUtils.isNotBlank(rst)){

            throw new BizException("-1","发放名册已存在");
        }


        OrderCaregiversDTO orderCaregiversDTO = orderCaregiversReadService.getCaregiverByIdcard(caregiverDto.getIdcard());

        if(orderCaregiversDTO != null){
            if(!caregiverDto.getCaregiverType().equals(orderCaregiversDTO.getCaregiverType())){
                String caregiverType;
                if(Constant.CaregiverType.PERSONAL.equals(orderCaregiversDTO.getCaregiverType())){
                    caregiverType = "个人";
                }else{
                    caregiverType = "机构";
                }
                throw new BizException("-1","该照料人已在系统作为"+caregiverType +"照料登记过，如需变更！请联系管理员确认");
            }
            caregiverDto.setId(orderCaregiversDTO.getId());
            this.updateCaregivers(caregiverDto);
        }else{


            this.insertCaregivers(caregiverDto);
        }


        this.insertCareLink(caregiverDto);

    }

    public void verifyOrderCaregiver(OrderCaregiversDTO caregiverDto,String caregiverId,String id,String caregiverType){
        if(StringUtils.isNotEmpty(caregiverDto.getOrderCertIds())){

            return;
        }


        int rst = orderCertReadService.cntCaregiverCertNum(caregiverDto.getOrderId(),caregiverId);
        if(rst <= 0){
            throw new BizException("-1", "当前照料人没有上传【照料协议】，请上传！");
        }

        if(Constant.CaregiverType.PERSONAL.equals(caregiverType)){

            int rstIdcard= orderCertReadService.cntCertNum(id,null,"102","18");


            if(rstIdcard <= 0){
                throw new BizException("-1", "当前信息没有上传【身份证照片】，请上传！");
            }

            int rstBank = orderCertReadService.cntCertNum(id,null,"401","18");

            if(rstBank <= 0){
                throw new BizException("-1", "当前信息没有上传【银行卡照片】，请上传！");
            }
        }else{

            int rstIdcard= orderCertReadService.cntCertNum(id,null,"888","18");

            if(rstIdcard <= 0){
                throw new BizException("-1", "当前信息没有上传【机构有效证件】，请上传！");
            }
        }


    }


    public void updateCaregiver(OrderCaregiversDTO caregiverDto, UserAccountVo accountVo) {

		this.verifyOrderCaregiver(caregiverDto,caregiverDto.getMemberId(),caregiverDto.getId(),caregiverDto.getCaregiverType());

        String memberKey = "Care"+caregiverDto.getMemberIdcard()+caregiverDto.getLinkId();
        String msgKey = (String) redisClusterUtils.get(memberKey);
        if(msgKey == null) {
            redisClusterUtils.set(memberKey, memberKey, 3);
        }else{
            throw new BizException("-1","该对象正在维护照料人信息,请刷新列表后重试");
        }
        OrderCareLinkEntity orderCareLinkEntity1 = orderCareLinkReadService.getById(caregiverDto.getLinkId());
        if(orderCareLinkEntity1 != null){
            if("02".equals(orderCareLinkEntity1.getState())){
                throw new BizException("-1","该对象照料人已变更或已注销,请刷新列表后重试");
            }

        }



        OrderCareLinkEntity orderCareLinkEntity = orderCareLinkReadService.getCareIdByIdCard(caregiverDto.getMemberIdcard());

        OrderCaregiversDTO orderCaregiversDTO = orderCaregiversReadService.getCaregiverByIdcard(caregiverDto.getIdcard());

        if(caregiverDto.getId().equals(orderCareLinkEntity.getCareId())){
            if(orderCaregiversDTO != null) {
                if (!caregiverDto.getCaregiverType().equals(orderCaregiversDTO.getCaregiverType())) {
                    String caregiverType;
                    if (Constant.CaregiverType.PERSONAL.equals(orderCaregiversDTO.getCaregiverType())) {
                        caregiverType = "个人";
                    } else {
                        caregiverType = "机构";
                    }
                    throw new BizException("-1", "该照料人已在系统作为" + caregiverType + "照料登记过，如需变更！请联系管理员确认");
                }
            }
            this.updateCaregivers(caregiverDto);



            OrderCareLinkEntity careLinkEntity = new OrderCareLinkEntity();
            careLinkEntity.setState("01");
            careLinkEntity.setId(caregiverDto.getLinkId());
            careLinkEntity.setCareIdcard(caregiverDto.getIdcard());
            careLinkEntity.setCareName(caregiverDto.getName());
            careLinkEntity.setCareBank(caregiverDto.getBankName());
            //careLinkEntity.setAccountName(caregiverDto.getAccountName());
            careLinkEntity.setAccount(caregiverDto.getAccount());
            careLinkEntity.setCareId(caregiverDto.getId());
            careLinkEntity.setMemberId(caregiverDto.getMemberId());
            careLinkEntity.setCaregiverRelation(caregiverDto.getCaregiverRelation());
            careLinkEntity.setUpdateTime(new Date());
            orderCareLinkWriteDao.updateByCareId(careLinkEntity);
        }else{
            String curMonth = DateUtil.beginOfMonth(new Date()).toString("yyyy-MM");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
            Date date = null;
            try {
                date = sdf.parse(curMonth);
            } catch (ParseException e) {
                e.printStackTrace();
            }



            String rst = fundPayReadService.verifyFundPayCareThrow(Constant.BusinessCode.TEKUN, accountVo.getAreaCode(),
                    caregiverDto.getStandType(), date, caregiverDto.getCaregiverTypeOld(),
                    Constant.FundType.CAPITAL_FUND_PAY);

            if(StringUtils.isNotBlank(rst)){

                throw new BizException("-1","变更前的发放名册类型已存在");
            }


            String rsts = fundPayReadService.verifyFundPayCareThrow(Constant.BusinessCode.TEKUN, accountVo.getAreaCode(),
                    caregiverDto.getStandType(), date, caregiverDto.getCaregiverType(),
                    Constant.FundType.CAPITAL_FUND_PAY);

            if(StringUtils.isNotBlank(rsts)){

                throw new BizException("-1","变更后的发放名册类型已存在");
            }



            if(orderCaregiversDTO != null){
                if(!caregiverDto.getCaregiverType().equals(orderCaregiversDTO.getCaregiverType())){
                    String caregiverType;
                    if(Constant.CaregiverType.PERSONAL.equals(orderCaregiversDTO.getCaregiverType())){
                        caregiverType = "个人";
                    }else{
                        caregiverType = "机构";
                    }
                    throw new BizException("-1","该照料人已在系统作为"+caregiverType +"照料登记过，如需变更！请联系管理员确认");
                }
                this.updateCaregivers(caregiverDto);
            }else{

                this.insertCaregivers(caregiverDto);
            }



            OrderCareLinkEntity careLinkEntity = new OrderCareLinkEntity();
            careLinkEntity.setState("02");
            careLinkEntity.setCareId(orderCareLinkEntity.getCareId());
            careLinkEntity.setId(caregiverDto.getLinkId());
            careLinkEntity.setMemberId(caregiverDto.getMemberId());

            String endMonth = DateUtil.parse(curMonth, "yyyy-MM").offset(DateField.MONTH,-1).toString("yyyy-MM-dd");
            careLinkEntity.setEndMonth(endMonth);
            careLinkEntity.setUpdateTime(new Date());
            orderCareLinkWriteDao.updateByCareId(careLinkEntity);



            this.insertCareLink(caregiverDto);


        }
    }


    public void deleteCaregiver(String id,String memberId,String standType,String caregiverType,UserAccountVo accountVo) {

        OrderCareLinkEntity orderCareLinkEntity1 = orderCareLinkReadService.getById(id);
        if(orderCareLinkEntity1 != null){
            if("02".equals(orderCareLinkEntity1.getState())){
                throw new BizException("-1","该对象照料人已注销,请刷新列表后重试");
            }

        }
        String curMonth = DateUtil.beginOfMonth(new Date()).toString("yyyy-MM");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        Date date = null;
        try {
            date = sdf.parse(curMonth);
        } catch (ParseException e) {
            e.printStackTrace();
        }



        String rst = fundPayReadService.verifyFundPayCareThrow(Constant.BusinessCode.TEKUN, accountVo.getAreaCode(),
                standType, date, caregiverType,
                Constant.FundType.CAPITAL_FUND_PAY);

        if(StringUtils.isNotBlank(rst)){

            throw new BizException("-1","发放名册已存在");
        }
        OrderCareLinkEntity careLinkEntity = new OrderCareLinkEntity();

        careLinkEntity.setState("02");
        careLinkEntity.setId(id);
        careLinkEntity.setMemberId(memberId);
        String endMonth = DateUtil.parse(curMonth, "yyyy-MM").offset(DateField.MONTH,-1).toString("yyyy-MM-dd");
        careLinkEntity.setEndMonth(endMonth);
        careLinkEntity.setUpdateTime(new Date());
        orderCareLinkWriteDao.updateByCareId(careLinkEntity);
    }


    public ExcelInfo exportCareList(CaregiverParam param, UserAccountVo accountVo) {

        QueryParamUtil.setBaseParamValue(param, accountVo);
        if(StringUtils.isEmpty(param.getSendMonth())){
            param.setSendMonth(com.mcxx.util.DateUtil.getMonthString());
        }

        List<OrderCareLinkExcelDTO> list = orderCareLinkReadDao.listCaregiverExcel(param);


        ExcelInfo excelInfo = exportExcelService.exportOrgOpLogs(OrderCareLinkExcelDTO.class,list,"照料人信息.xls",
                "照料人信息","照料人信息",false,null);



        return excelInfo;
    }
}
